<template>
  <div class="notary-container">
    <div class="notary-card">
      <div class="notary-header">
        <h2>文件公证中心</h2>
        <p>安全、可靠的电子文件公证服务</p>
      </div>
      
      <div class="notary-body">
        <!-- 文件公证区域 -->
        <el-card shadow="hover" class="upload-section">
          <div class="section-header">
            <el-icon><Upload /></el-icon>
            <span>文件公证</span>
          </div>
          <el-upload
            ref="notarizeUpload"
            drag
            :auto-upload="false"
            :on-change="handleNotarizeChange"
            :show-file-list="false"
            class="upload-area"
            :disabled="notarizeLoading"
          >
            <el-icon class="upload-icon" v-if="!notarizeFile"><Upload /></el-icon>
            <div v-if="notarizeFile" class="file-preview">
              <el-icon class="file-icon"><Document /></el-icon>
              <div class="file-info">
                <p>{{ notarizeFile.name }}</p>
                <p class="file-size">{{ formatFileSize(notarizeFile.size) }}</p>
              </div>
            </div>
            <div v-else class="upload-text">
              <p>点击或拖拽文件到此处</p>
              <p class="upload-hint">支持PDF、DOC、JPG等格式</p>
            </div>
          </el-upload>
          
          <div class="actions" v-if="notarizeFile">
            <el-button type="danger" plain @click="clearNotarizeFile" :disabled="notarizeLoading">
              <el-icon><Delete /></el-icon> 清除文件
            </el-button>
            <el-button type="primary" @click="submitNotarize" :loading="notarizeLoading" round>
              <template v-if="!notarizeLoading">开始公证</template>
              <template v-else>公证中...</template>
            </el-button>
          </div>
          
          <div v-if="notarizeResult" class="result-section">
            <el-divider />
            <div class="result-header">
              <el-icon :color="notarizeSuccess ? '#67c23a' : '#f56c6c'">
                <CircleCheckFilled v-if="notarizeSuccess" />
                <CircleCloseFilled v-else />
              </el-icon>
              <h3 :class="{'success-text': notarizeSuccess, 'error-text': !notarizeSuccess}">
                {{ notarizeSuccess ? '文件公证成功' : '文件公证失败' }}
              </h3>
            </div>
            
            <div class="result-content">
              <el-descriptions :column="1" border>
                <el-descriptions-item label="文件哈希" v-if="notarizeResult.originalHash">
                  {{ truncateText(notarizeResult.originalHash, 20) }}
                  <el-tooltip effect="dark" :content="notarizeResult.originalHash" placement="top">
                    <el-icon><InfoFilled /></el-icon>
                  </el-tooltip>
                </el-descriptions-item>
                <el-descriptions-item label="公证时间">
                  {{ formatDate(notarizeResult.encryptedAt) }}
                </el-descriptions-item>
                <el-descriptions-item label="文件ID">
                  {{ notarizeResult.fileId }}
                </el-descriptions-item>
                <!-- 新增：显示用户信息 -->
                <el-descriptions-item label="公证用户">
                  {{ notarizeResult.username }}
                </el-descriptions-item>
         
              </el-descriptions>
              
              <div class="download-area" v-if="notarizeSuccess">
                <p>已生成加密文件，点击下载：</p>
                <el-button type="primary" @click="downloadEncryptedFile" round>
                  <el-icon><Download /></el-icon> 下载加密文件
                </el-button>
              </div>
            </div>
          </div>
        </el-card>
        
        <el-divider>
          <el-icon><Switch /></el-icon>
        </el-divider>
        
        <!-- 文件验证区域 -->
        <el-card shadow="hover" class="verify-section">
          <div class="section-header">
            <el-icon><DocumentChecked /></el-icon>
            <span>文件验证</span>
          </div>
          <el-upload
            ref="verifyUpload"
            drag
            :auto-upload="false"
            :on-change="handleVerifyChange"
            :show-file-list="false"
            class="upload-area"
            :disabled="verifyLoading"
          >
            <el-icon class="upload-icon" v-if="!verifyFile"><Document /></el-icon>
            <div v-if="verifyFile" class="file-preview">
              <el-icon class="file-icon"><Document /></el-icon>
              <div class="file-info">
                <p>{{ verifyFile.name }}</p>
                <p class="file-size">{{ formatFileSize(verifyFile.size) }}</p>
              </div>
            </div>
            <div v-else class="upload-text">
              <p>上传公证文件进行验证</p>
              <p class="upload-hint">验证文件完整性和所有权</p>
            </div>
          </el-upload>
          
          <div class="actions" v-if="verifyFile">
            <el-button type="danger" plain @click="clearVerifyFile" :disabled="verifyLoading">
              <el-icon><Delete /></el-icon> 清除文件
            </el-button>
            <el-button type="success" @click="submitVerify" :loading="verifyLoading" round>
              <template v-if="!verifyLoading">验证文件</template>
              <template v-else>验证中...</template>
            </el-button>
          </div>
          
          <!-- 验证结果区域 -->
          <div v-if="verifyResult" class="result-section">
            <el-divider />
            <div class="result-header">
              <el-icon :color="verifySuccess ? '#67c23a' : '#f56c6c'">
                <CircleCheckFilled v-if="verifySuccess" />
                <CircleCloseFilled v-else />
              </el-icon>
              <h3 :class="{'success-text': verifySuccess, 'error-text': !verifySuccess}">
                {{ verifyResult.message }}
              </h3>
            </div>
            
            <div class="result-content">
              <el-descriptions :column="2" border>
                <el-descriptions-item label="原始文件长度">
                  {{ verifyResult.originalLength }} 字节
                </el-descriptions-item>
                <el-descriptions-item label="恢复字节数">
                  {{ verifyResult.recoveredBytes }} 字节
                </el-descriptions-item>
                <el-descriptions-item label="质量评分">
                  <el-progress 
                    :percentage="verifyResult.qualityScore" 
                    :status="verifyResult.qualityScore >= 80 ? 'success' : 
                             verifyResult.qualityScore >= 50 ? 'warning' : 'exception'"
                    :text-inside="true"
                    :stroke-width="20"
                  />
                </el-descriptions-item>
                <el-descriptions-item label="验证状态">
                  <el-tag :type="verifyResult.valid ? 'success' : 'danger'">
                    {{ verifyResult.valid ? '验证通过' : '验证失败' }}
                  </el-tag>
                  <el-tag :type="verifyResult.tampered ? 'danger' : 'success'" style="margin-left: 8px">
                    {{ verifyResult.tampered ? '文件被篡改' : '文件完整' }}
                  </el-tag>
                </el-descriptions-item>
                <!-- 新增：显示用户信息 -->
                <el-descriptions-item label="公证用户">
                  {{ verifyResult.username || '未知用户' }}
                </el-descriptions-item>
              
              </el-descriptions>
              
              <div class="recovery-section" v-if="verifyResult.originalFile">
                <p>文件验证通过，可下载原始文件：</p>
                <el-button type="primary" @click="downloadOriginalFile" round>
                  <el-icon><Download /></el-icon> 下载原始文件
                </el-button>
              </div>
              
              <div class="recovery-section" v-if="verifyResult.recoveredFile">
                <p>检测到文件被篡改，已恢复部分数据：</p>
                <el-button type="warning" @click="downloadRecoveredFile" round>
                  <el-icon><Download /></el-icon> 下载恢复文件
                </el-button>
              </div>
            </div>
          </div>
          
          <!-- 新增：验证状态为"无"时的显示 -->
          <div v-else-if="verifyStatus === 'none'" class="result-section">
            <el-divider />
            <div class="result-header">
              <el-icon><Warning /></el-icon>
              <h3 class="warning-text">验证状态: 无</h3>
            </div>
            <div class="result-content">
              <p>未获取到有效的验证结果</p>
            </div>
          </div>
        </el-card>
      </div>
      
      <div class="notary-footer">
        <div class="bottom-right-button">
          <el-button @click="goBackToFileSystem">返回主页面</el-button>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref } from 'vue';
import axios from 'axios';
import { ElMessage } from 'element-plus';
import {
  Upload,
  Document,
  DocumentChecked,
  Switch,
  Delete,
  Download,
  CircleCheckFilled,
  CircleCloseFilled,
  InfoFilled,
  Warning
} from '@element-plus/icons-vue';

// 状态变量
const notarizeFile = ref(null);
const verifyFile = ref(null);
const notarizeLoading = ref(false);
const verifyLoading = ref(false);
const notarizeResult = ref(null);
const verifyResult = ref(null);
const encryptedFileBlob = ref(null);
const recoveredFileBlob = ref(null);

// 新增验证状态变量
const verifyStatus = ref(null); // 'success', 'fail', 'none'

// 计算属性
const notarizeSuccess = ref(false);
const verifySuccess = ref(false);

// API端点
const encryptApiUrl = 'http://localhost:8083/nota/encrypt';
const verifyApiUrl = 'http://localhost:8083/nota/verify';

// 文件处理函数
const handleNotarizeChange = (file) => {
  notarizeFile.value = file.raw;
};

const handleVerifyChange = (file) => {
  verifyFile.value = file.raw;
};

const clearNotarizeFile = () => {
  notarizeFile.value = null;
  notarizeResult.value = null;
};

const clearVerifyFile = () => {
  verifyFile.value = null;
  verifyResult.value = null;
  verifyStatus.value = null; // 清除时重置状态
};

// 提交公证
const submitNotarize = async () => {
  if (!notarizeFile.value) {
    ElMessage.warning('请选择要公证的文件');
    return;
  }
  
  try {
    notarizeLoading.value = true;
    
    const formData = new FormData();
    formData.append('file', notarizeFile.value);
    
    const response = await axios.post(encryptApiUrl, formData, {
      responseType: 'blob',
      headers: {
        'Content-Type': 'multipart/form-data'
      }
    });
    
    // 保存加密文件
    encryptedFileBlob.value = response.data;
    
    // 获取响应头信息
    const encryptedAtHeader = response.headers['x-encrypted-at'];
    const originalHash = response.headers['x-original-hash'];
    const fileId = response.headers['x-file-id'];
    const userId = response.headers['x-user-id'];
    const username = response.headers['x-user-id']; // 从后端获取用户名
    
    // 处理结果数据
    notarizeResult.value = {
      originalHash: originalHash || '无记录',
      fileId: fileId || '未生成',
      encryptedAt: encryptedAtHeader ? new Date(encryptedAtHeader) : null,
      userId: userId || '未知用户',
      username: username || '未知用户' // 添加用户名
    };
    
    notarizeSuccess.value = true;
    ElMessage.success('文件公证成功');
 
  } catch (error) {
    console.error('公证失败:', error);
    
    // 创建错误结果对象
    notarizeResult.value = { 
      error: error.message || '公证失败，请重试',
      originalHash: '获取失败',
      fileId: 'N/A',
      encryptedAt: new Date(),
      userId: '未知',
      username: '未知'
    };
    
    notarizeSuccess.value = false;
    
    // 错误处理逻辑
    let errorMessage = '公证失败，请重试';
    
    if (error.response) {
      // 处理400错误
      if (error.response.status === 400) {
        try {
          if (error.response.data instanceof Blob) {
            const errorText = await error.response.data.text();
            try {
              const errorData = JSON.parse(errorText);
              errorMessage = errorData.errorMsg || '非法请求参数';
            } catch (jsonError) {
              errorMessage = errorText || '非法请求参数';
            }
          } 
          else if (error.response.data.errorMsg) {
            errorMessage = error.response.data.errorMsg;
          } else if (typeof error.response.data === 'string') {
            errorMessage = error.response.data;
          }
        } catch (parseError) {
          console.error('解析错误响应失败:', parseError);
          errorMessage = '非法请求参数';
        }
      } else {
        errorMessage = `请求错误: ${error.response.status} ${error.response.statusText}`;
      }
    } else if (error.request) {
      errorMessage = '请求未得到响应';
    } else {
      errorMessage = error.message || '未知网络错误';
    }
    
    ElMessage.error(errorMessage);
  } finally {
    notarizeLoading.value = false;
  }
};

// 提交验证
const submitVerify = async () => {
  if (!verifyFile.value) {
    ElMessage.warning('请选择要验证的文件');
    return;
  }
  
  try {
    // 重置状态
    verifyStatus.value = null;
    verifyResult.value = null;
    verifyLoading.value = true;
    
    const formData = new FormData();
    formData.append('file', verifyFile.value);
    
    const response = await axios.post(verifyApiUrl, formData, {
      headers: {
        'Content-Type': 'multipart/form-data'
      }
    });
    
    verifyResult.value = response.data;
    
    // 处理恢复文件
    if (verifyResult.value.recoveredFile) {
      recoveredFileBlob.value = base64ToBlob(verifyResult.value.recoveredFile);
    }
    
    // 使用valid字段判断验证成功
    verifySuccess.value = verifyResult.value.valid;
    
    // 设置验证状态
    verifyStatus.value = verifyResult.value.valid ? 'success' : 'fail';
    
    if (verifySuccess.value) {
      ElMessage.success('文件验证成功');
    } else {
      ElMessage.warning('文件验证未完全通过: ' + (verifyResult.value.message || '未知原因'));
    }
  } catch (error) {
    console.error('验证失败:', error);
    
    let errorMessage = '验证失败，请重试';
    
    // 处理不同类型的错误
    if (error.response) {
      try {
        if (error.response.data?.errorMsg) {
          errorMessage = error.response.data.errorMsg;
        } 
        else if (error.response.data?.message) {
          errorMessage = error.response.data.message;
        }
        else if (error.response.data instanceof Blob) {
          const errorText = await error.response.data.text();
          try {
            const errorData = JSON.parse(errorText);
            errorMessage = errorData.errorMsg || errorData.message || '非法请求参数';
          } catch {
            errorMessage = errorText || '非法请求参数';
          }
        }
        else if (typeof error.response.data === 'string') {
          errorMessage = error.response.data;
        }
        else if (error.response.status === 400) {
          errorMessage = '非法请求参数';
        } else if (error.response.status === 401) {
          errorMessage = '未授权访问';
        } else if (error.response.status === 404) {
          errorMessage = '资源未找到';
        } else if (error.response.status === 500) {
          errorMessage = '服务器内部错误';
        } else {
          errorMessage = `请求错误: ${error.response.status} ${error.response.statusText}`;
        }
      } catch (parseError) {
        console.error('解析错误响应失败:', parseError);
        errorMessage = '处理错误信息时发生问题';
      }
    } else if (error.request) {
      errorMessage = '请求未得到响应，请检查网络连接';
    } else {
      errorMessage = error.message || '未知网络错误';
    }
    
    // 设置验证状态为"无"
    verifyStatus.value = 'none';
    
    ElMessage.error(errorMessage);
  } finally {
    verifyLoading.value = false;
  }
};

// Base64转Blob工具函数
const base64ToBlob = (base64Data) => {
  try {
    const mimeMatch = base64Data.match(/^data:(.+);base64,/);
    const mimeType = mimeMatch ? mimeMatch[1] : 'application/octet-stream';
    const base64WithoutPrefix = base64Data.replace(/^data:.+;base64,/, '');
    
    const byteCharacters = atob(base64WithoutPrefix);
    const byteArrays = [];
    
    for (let offset = 0; offset < byteCharacters.length; offset += 1024) {
      const slice = byteCharacters.slice(offset, offset + 1024);
      
      const byteNumbers = new Array(slice.length);
      for (let i = 0; i < slice.length; i++) {
        byteNumbers[i] = slice.charCodeAt(i);
      }
      
      const byteArray = new Uint8Array(byteNumbers);
      byteArrays.push(byteArray);
    }
    
    return new Blob(byteArrays, { type: mimeType });
  } catch (e) {
    console.error('Base64转换失败:', e);
    ElMessage.error('恢复文件处理失败');
    return null;
  }
};

// 下载原始文件
const downloadOriginalFile = () => {
  if (!verifyResult.value.originalFile) return;
  
  const blob = base64ToBlob(verifyResult.value.originalFile);
  const url = URL.createObjectURL(blob);
  const link = document.createElement('a');
  link.href = url;
  
  let fileName = verifyFile.value.name;
  if (fileName.startsWith('encrypted_')) {
    fileName = fileName.replace('encrypted_', '');
  } else {
    fileName = 'decrypted_' + fileName;
  }
  
  link.download = fileName;
  document.body.appendChild(link);
  link.click();
  document.body.removeChild(link);
  URL.revokeObjectURL(url);
};

// 下载加密文件
const downloadEncryptedFile = () => {
  if (!encryptedFileBlob.value) return;
  
  const url = URL.createObjectURL(encryptedFileBlob.value);
  const link = document.createElement('a');
  link.href = url;
  link.download = `encrypted_${notarizeFile.value.name}`;
  document.body.appendChild(link);
  link.click();
  document.body.removeChild(link);
  URL.revokeObjectURL(url);
};

// 下载恢复文件
const downloadRecoveredFile = () => {
  if (!recoveredFileBlob.value) return;
  
  const url = URL.createObjectURL(recoveredFileBlob.value);
  const link = document.createElement('a');
  link.href = url;
  
  const originalFileName = verifyFile.value.name;
  const fileNameParts = originalFileName.split('.');
  let extension = '';
  let baseName = originalFileName;
  
  if (fileNameParts.length > 1) {
    extension = fileNameParts.pop();
    baseName = fileNameParts.join('.');
  }
  
  const fileName = `${baseName}_recovered${extension ? '.' + extension : ''}`;
  
  link.download = fileName;
  document.body.appendChild(link);
  link.click();
  document.body.removeChild(link);
  URL.revokeObjectURL(url);
};

// 工具函数
const formatFileSize = (bytes) => {
  if (bytes === 0) return '0 Bytes';
  const k = 1024;
  const sizes = ['Bytes', 'KB', 'MB', 'GB'];
  const i = Math.floor(Math.log(bytes) / Math.log(k));
  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
};

const truncateText = (text, maxLength) => {
  if (!text) return '';
  if (text.length <= maxLength) return text;
  return text.substring(0, maxLength) + '...';
};

// 日期格式化
const formatDate = (date) => {
  if (!date) return '无记录';
  
  try {
    if (date instanceof Date) {
      return date.toLocaleString();
    }
    
    if (typeof date === 'string') {
      return new Date(date).toLocaleString();
    }
    
    return '无效时间格式';
  } catch (e) {
    console.error('日期解析错误:', e);
    return '解析失败';
  }
};

// 返回主页面
const goBackToFileSystem = () => {
  window.location.href = '/filesystem';
};
</script>

<style scoped>
.notary-container {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 100vh;
  background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
  padding: 20px;
}

.notary-card {
  width: 100%;
  max-width: 900px;
  background: white;
  border-radius: 16px;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
  overflow: hidden;
}

.notary-header {
  padding: 30px;
  text-align: center;
  background: linear-gradient(135deg, #6b73ff 0%, #000dff 100%);
  color: white;
}

.notary-header h2 {
  margin: 0;
  font-size: 28px;
}

.notary-header p {
  margin: 10px 0 0;
  opacity: 0.9;
}

.notary-body {
  padding: 30px;
}

.upload-section, .verify-section {
  margin-bottom: 30px;
  border: none;
  transition: transform 0.3s ease, box-shadow 0.3s ease;
}

.upload-section:hover, .verify-section:hover {
  transform: translateY(-5px);
  box-shadow: 0 15px 35px rgba(0, 0, 0, 0.15);
}

.section-header {
  display: flex;
  align-items: center;
  margin-bottom: 20px;
  font-size: 18px;
  color: #333;
}

.section-header .el-icon {
  margin-right: 10px;
  font-size: 24px;
}

.upload-area {
  margin-bottom: 20px;
  border-radius: 10px;
  overflow: hidden;
  border: 1px dashed #dcdfe6;
  background: #fafafa;
}

.upload-area:hover {
  border-color: #409eff;
}

.upload-icon {
  font-size: 50px;
  color: #409eff;
  margin-bottom: 20px;
}

.upload-text {
  line-height: 1.5;
  text-align: center;
  padding: 20px;
}

.upload-hint {
  font-size: 14px;
  color: #999;
  margin-top: 8px;
}

.file-preview {
  display: flex;
  align-items: center;
  padding: 15px;
  background: #f8f8f8;
  border-radius: 8px;
}

.file-icon {
  font-size: 40px;
  color: #409eff;
  margin-right: 15px;
}

.file-info {
  text-align: left;
}

.file-info p {
  margin: 0;
}

.file-size {
  font-size: 14px;
  color: #666;
  margin-top: 5px;
}

.actions {
  display: flex;
  justify-content: space-between;
  margin-top: 15px;
  gap: 15px;
}

.result-section {
  margin-top: 20px;
  padding: 15px;
  background: #f9fafc;
  border-radius: 10px;
  border: 1px solid #ebeef5;
}

.result-header {
  display: flex;
  align-items: center;
  margin-bottom: 15px;
}

.result-header h3 {
  margin: 0 0 0 10px;
  font-size: 18px;
}

.success-text {
  color: #67c23a;
}

.error-text {
  color: #f56c6c;
}

.warning-text {
  color: #e6a23c;
}

.result-content {
  padding: 10px;
}

.download-area, .recovery-section {
  margin-top: 20px;
  text-align: center;
  padding: 15px;
  background-color: #f0f7ff;
  border-radius: 8px;
  border: 1px dashed #409eff;
}

.download-area p, .recovery-section p {
  margin-bottom: 15px;
  color: #333;
}

.notary-footer {
  padding: 20px;
  text-align: center;
  background: #f9f9f9;
  color: #666;
  font-size: 14px;
  border-top: 1px solid #eee;
}

.bottom-right-button {
  display: flex;
  justify-content: flex-end;
  padding: 10px 20px;
}

.el-divider {
  margin: 30px 0;
}

.el-divider .el-icon {
  background: #fff;
  padding: 0 10px;
  color: #409eff;
}

.progress-container {
  display: flex;
  align-items: center;
  gap: 10px;
}

.progress-label {
  min-width: 80px;
}

.el-tag {
  font-weight: 500;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .notary-card {
    border-radius: 12px;
  }
  
  .notary-body {
    padding: 15px;
  }
  
  .actions {
    flex-direction: column;
    gap: 10px;
  }
  
  .actions .el-button {
    width: 100%;
  }
  
  .el-descriptions {
    :deep(.el-descriptions__cell) {
      display: block;
      width: 100%;
    }
  }
}
</style>